package com.zdp.chat.handler;

import com.alibaba.fastjson.JSON;
import com.zdp.chat.entity.chat.ChatMessageReq;
import com.zdp.chat.enums.ContextTypeEnum;
import com.zdp.chat.util.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.lang.reflect.ParameterizedType;
import java.util.Arrays;

@Slf4j
public abstract class AbstractChatMessageHandler<B, I, R> {

    public abstract boolean apply(Integer messageType);

    public final void handler(ChatMessageReq<B> req) {
        B b = this.preValidation(req);
        I inner = this.convertInner(b);
        roomHandler(inner);
        saveMessage(inner);
        publishMessageEvent(inner);
    }

    // 校验请求对象是否合法
    protected B preValidation(ChatMessageReq<B> req) {
        ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
        Class<B> typeArgument = (Class<B>) genericSuperclass.getActualTypeArguments()[0];
        B b = JSON.parseObject(JSON.toJSONString(req.getData()), typeArgument);
        Assert.isTrue(ObjectUtils.isFieldAllNotEmpty(b), "参数不合法");
        String messageType = Arrays.stream(ContextTypeEnum.values()).filter(x -> x.getType().equals(req.getMsgType())).findFirst().get().getDesc();
        log.info("消息类型:{},消息对象:{}", messageType, JSON.toJSONString(b));
        return b;
    }

    // 请求对象 --> 内部消息对象
    protected abstract I convertInner(B b);

    // 处理房间
    protected abstract void roomHandler(I i);

    // 保存消息
    protected abstract void saveMessage(I i);

    // 发布消息事件(及时发送消息)
    protected abstract void publishMessageEvent(I i);

    // 内部对象 --> 外部响应对象
    protected abstract R convertResp(I i);


}
